#ifndef _RINGQUEUE_HPP_
#define _RINGQUEUE_HPP_
#include <iostream>
#include <semaphore.h>
#include <string>
#include <vector>
#include <pthread.h>
#include <unistd.h>

using DataType = int;
static int DEFAULT = 5;
template<typename T>
class RingQueue
{
private:
    void P(sem_t& sem)
    {
        sem_wait(&sem);
    }

    void V(sem_t& sem)
    {
        sem_post(&sem);
    }

public:
    RingQueue(int maxcap = DEFAULT)
        : _MaxCap(maxcap), _ringQueue(maxcap), _p_index(0), _c_index(0)
    {
        // 初始化信号量
        sem_init(&_Space_sem, 0, _MaxCap);
        sem_init(&_Data_sem, 0, 0);
    }
    void Push(const T &data)
    {
        // 先申请信号量预定空间资源
        P(_Space_sem);

        _ringQueue[_p_index] = data;
        _p_index = (++_p_index) % _MaxCap;

        V(_Data_sem);
    }
    void Pop(T *OutData)
    {
        // 先申请信号量预定data资源
        P(_Data_sem);

        *OutData = _ringQueue[_c_index];
        _c_index = (++_c_index) % _MaxCap;

        V(_Space_sem);
    }
    ~RingQueue()
    {
        // 销毁信号量
        sem_destroy(&_Space_sem);
        sem_destroy(&_Data_sem);
    }

private:
    std::vector<T> _ringQueue;
    int _MaxCap;
    int _p_index;     // 生产者下标
    int _c_index;     // 消费者下标
    sem_t _Space_sem; // 生产者信号量
    sem_t _Data_sem;  // 消费者信号量
};

#endif
